package com.scs.application.modules.svn;

import com.scs.application.core.utils.DateUtils;
import com.scs.application.core.utils.StringUtils;
import com.scs.application.core.utils.Tools;
import com.scs.application.modules.svn.dto.SVNLockInfo;
import com.scs.application.modules.svn.enums.SVNFileLockStatus;
import org.tmatesoft.svn.core.SVNDepth;
import org.tmatesoft.svn.core.SVNLock;
import org.tmatesoft.svn.core.internal.io.dav.DAVRepositoryFactory;
import org.tmatesoft.svn.core.internal.io.svn.SVNRepositoryFactoryImpl;
import org.tmatesoft.svn.core.wc.SVNClientManager;
import org.tmatesoft.svn.core.wc.SVNRevision;
import org.tmatesoft.svn.core.wc.SVNStatus;
import org.tmatesoft.svn.core.wc.SVNStatusClient;
import org.tmatesoft.svn.core.wc2.SvnCleanup;
import org.tmatesoft.svn.core.wc2.SvnCommit;
import org.tmatesoft.svn.core.wc2.SvnOperationFactory;
import org.tmatesoft.svn.core.wc2.SvnTarget;

import java.io.File;

/**
 */
public class SVNHelper {
    /**
     *返回文件锁定者
     *
     * @return 返回锁定的工作站，未锁定返回null
     */

    public static SVNLockInfo getLockInfo(File file) throws Exception {
        if (!file.exists()) {
            return  new SVNLockInfo(SVNFileLockStatus.NONE);
        }
        SVNRepositoryFactoryImpl.setup();
        SVNStatus svnStatus = SVNClientManager.newInstance()
                .getStatusClient()
                .doStatus(file, true);
        if (svnStatus == null) {
            return new SVNLockInfo(SVNFileLockStatus.DRAFT);
        }
        else if (svnStatus.getNodeStatus().getCode() == 'A' || svnStatus.getNodeStatus().toString().equals("unversioned")) {
            return new SVNLockInfo(SVNFileLockStatus.ADDED);
        }
        else if (svnStatus.getNodeStatus().getCode() == 'D') {
            return new SVNLockInfo(SVNFileLockStatus.DELETED);
        }

        SVNLock svnLock = svnStatus.getRemoteLock();
        if (svnLock == null) {
            return new SVNLockInfo(SVNFileLockStatus.FREE);
        }
        else if(svnLock.getComment().equalsIgnoreCase(Tools.getHostName())) {
            return new SVNLockInfo(SVNFileLockStatus.LOCK_BY_SELF, svnLock.getOwner(), svnLock.getComment());
        }
        else {
            return new SVNLockInfo(SVNFileLockStatus.LOCK, svnLock.getOwner(), svnLock.getComment());
        }
    }
    /**
     *清除文件状态
     *
     * @return
     */
    public static void cleanupFile(File path) throws Exception {
        File root = SvnOperationFactory.getWorkingCopyRoot(path, true);
        SvnCleanup svnCleanup = new SvnOperationFactory().createCleanup();
        svnCleanup.setBreakLocks(true);
        svnCleanup.setVacuumPristines(true);
        svnCleanup.setDeleteWCProperties(true);
        svnCleanup.setIncludeExternals(true);
        svnCleanup.setSingleTarget(SvnTarget.fromFile(root));
        svnCleanup.setDeleteWCProperties(true);
        svnCleanup.run();

//        SVNRepositoryFactoryImpl.setup();
//        SVNClientManager.newInstance()
//                .getWCClient()
//                .doCleanup(path);
    }
    /**
     *锁定文件
     *
     * @return
     */
    public static void lockFile(File file) throws Exception{
        SVNRepositoryFactoryImpl.setup();
        SVNClientManager.newInstance()
                .getWCClient()
                .doLock(new File[]{file}, false, Tools.getHostName());
    }
    /**
     *解除锁定文件
     *
     * @return
     */
    public static void unLockFile(File file) throws Exception{
        SVNRepositoryFactoryImpl.setup();
        SVNClientManager.newInstance()
                .getWCClient()
                .doUnlock(new File[]{file}, false);
    }
    /**
     *添加文件
     *
     * @return
     */
    public static void addFile(File file) throws Exception {
        SVNRepositoryFactoryImpl.setup();
        SVNClientManager.newInstance()
                .getWCClient()
                .doAdd(file, false, false, true, SVNDepth.INFINITY, false, true);
    }
    /**
     *更新单个文件
     *
     * @return 最新的版本号
     */
    public static Long updateFile(File file) throws Exception {
        DAVRepositoryFactory.setup();
        return SVNClientManager.newInstance()
                .getUpdateClient()
                .doUpdate(file, SVNRevision.HEAD, SVNDepth.INFINITY, false, false);
    }
    /**
     *提交文件
     *
     * @return
     */
//    public static void commitFile(File file, String message) throws Exception {
//        SVNRepositoryFactoryImpl.setup();
//        String commitMessage = Tools.getHostName() + " 于 " + DateUtils.now() + " 提交：" + message;
//        SVNClientManager.newInstance()
//                .getCommitClient()
//                .doCommit(new File[] { file }, true, commitMessage, null,null, true, false, SVNDepth.INFINITY);
//    }
    public static void commitFile(File file, String message) throws Exception {

        String commitMessage = Tools.getHostName() + " 于 " + DateUtils.now() + " 提交：" + message;
        if (StringUtils.isNotBlank(message)) commitMessage= message;
        SvnCommit svnCommit = new SvnOperationFactory().createCommit();
        svnCommit.setSingleTarget(SvnTarget.fromFile(file));
        svnCommit.setCommitMessage(commitMessage);
        svnCommit.setDepth(SVNDepth.INFINITY);
        svnCommit.setKeepLocks(false);
        svnCommit.run();
    }
    public static void commitFile(File file) throws Exception {
        commitFile(file, "无");
    }
    /**
     *撤销提交文件
     *
     * @return
     */
    public static void revertFile(File file) throws Exception {
        SVNRepositoryFactoryImpl.setup();
        SVNClientManager.newInstance()
                .getWCClient()
                .doRevert(new File[] { file }, SVNDepth.INFINITY, null);
    }
    /**
     *删除文件
     *
     * @return
     */
    public static void deleteFile(File file) throws Exception {
        SVNRepositoryFactoryImpl.setup();
        SVNClientManager.newInstance()
                .getWCClient()
                .doDelete(file, true, true,false);
    }

    /**
     *返回文件锁定者
     *
     * @return 返回锁定的工作站，未锁定返回null
     */

    public static SVNLockInfo getLockInfo(SVNStatusClient svnStatusClient,File file) throws Exception {
        if (!file.exists()) {
            return  new SVNLockInfo(SVNFileLockStatus.NONE);
        }
        SVNStatus svnStatus = svnStatusClient.doStatus(file, true);
        return getLockInfoBySVNStatus(svnStatus);
    }

    /**
     *返回文件锁定者
     *
     * @return 返回锁定的工作站，未锁定返回null
     */

    public static SVNLockInfo getLockInfoBySVNStatus(SVNStatus svnStatus) throws Exception {
        if (svnStatus == null) {
            return new SVNLockInfo(SVNFileLockStatus.DRAFT);
        }
        else if (svnStatus.getNodeStatus().getCode() == 'A') {
            return new SVNLockInfo(SVNFileLockStatus.ADDED);
        }
        else if (svnStatus.getNodeStatus().getCode() == 'D') {
            return new SVNLockInfo(SVNFileLockStatus.DELETED);
        }

        SVNLock svnLock = svnStatus.getRemoteLock();
        if (svnLock == null) {
            return new SVNLockInfo(SVNFileLockStatus.FREE);
        }
        else if(svnLock.getComment().equalsIgnoreCase(Tools.getHostName())) {
            return new SVNLockInfo(SVNFileLockStatus.LOCK_BY_SELF, svnLock.getOwner(), svnLock.getComment());
        }
        else {
            return new SVNLockInfo(SVNFileLockStatus.LOCK, svnLock.getOwner(), svnLock.getComment());
        }
    }
}
